package com.sxl.main;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author songxulin
 * @date 2023/10/10
 */
public class PaxosAlgorithm {
    /**
     * 提案编号
     */
    private int proposalNumber;
    /**
     * 已接受的提案编号
     */
    private Map<Integer, String> acceptedProposals;
    /**
     * 待选提案
     */
    private Map<Integer, Integer> quasiProposals;

    private List<PaxosAlgorithm> members;

    public PaxosAlgorithm(List<PaxosAlgorithm> members) {
        this.members = members;
        proposalNumber = 0;
        acceptedProposals = new HashMap<>();
        quasiProposals = new HashMap<>();
    }

    public  void prepare(int proposalNumber) {
        if (proposalNumber > this.proposalNumber) {
            this.proposalNumber = proposalNumber;
        }
    }

    public  void accept(int proposalNumber, String value) {
        if (proposalNumber >= this.proposalNumber) {
            this.proposalNumber = proposalNumber;
            acceptedProposals.put(proposalNumber, value);
        }
    }

    public void learn(int proposalNumber, String value) {
        // 从接受者处学习已接受的值
        Integer count = quasiProposals.get(proposalNumber);
        if (count==null){
            count =0;
        }else {

        }
    }

    public synchronized String decide() {
        int maxProposalNumber = -1;
        String decidedValue = null;
        for (Map.Entry<Integer, String> entry : acceptedProposals.entrySet()) {
            if (entry.getKey() > maxProposalNumber) {
                maxProposalNumber = entry.getKey();
                decidedValue = entry.getValue();
            }
        }
        return decidedValue;
    }

    public static void main(String[] args) {
        PaxosAlgorithm paxos = new PaxosAlgorithm(null);
        // 提议者
        Thread proposer1 = new Thread(() -> {
            paxos.prepare(2);
            paxos.accept(2, "Value2");
        });
        // 接受者
        Thread acceptor1 = new Thread(() -> {
            paxos.prepare(1);
            paxos.accept(1, "Value1");
        });
        proposer1.start();
        acceptor1.start();
        try {
            proposer1.join();
            acceptor1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        String decidedValue = paxos.decide();
        System.out.println("Decided value: " + decidedValue);
    }
}